#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <errno.h>
#include <signal.h>
#include <highgui.h>
#include <cxcore.h>
#include "config.h"
#include "imagem.h"

/*
	Parâmetros
	--número do dispositivo de imagem
	--número da porta de comunicação com o openoffice
	--coordenadas topleft
	--coordenadas bottomright
*/

FILE *penserver;
Imagem *rgb;

static void sair(int signum);
static void evento_mouse(int event, int x, int y, int flags, void *params);

int main(int argc, char* argv[]) {
	char tecla;
	char msg[9];
	char cmd[30];
	unsigned long int porta = 1987;
	unsigned short int dispositivo = 0;
	int topleftx = 0, toplefty = 0;
	int bottomrightx = WIDTH, bottomrighty = HEIGHT;
	int c;
	int option_index = 0;
	short int continuar = 1;
	Imagem a;
	rgb = &a;
	ImagemInicializar(rgb);
	double contraste = LASER_CONTRASTE, brilho = LASER_BRILHO;
	//Analisando os argumentos
	while(1) {
		static struct option long_options[] = {
			{"dispositivo", required_argument, NULL, 'd'},
			{"porta",		required_argument, NULL, 'p'},
			{"topleftx",	required_argument, NULL, '1'},
			{"toplefty",	required_argument, NULL, '2'},
			{"bottomrightx",required_argument, NULL, '3'},
			{"bottomrighty",required_argument, NULL, '4'}
		};
		c = getopt_long (argc, argv, "d:p:1:2:3:4:",
						 long_options, &option_index);
		if(c == -1)
			break;
		switch(c) {
			case 'd':
				dispositivo = atoi(optarg);
				break;
			case 'p':
				porta = atol(optarg);
				break;
			case '1':
				topleftx = atoi(optarg);
				if(topleftx < 0)
					topleftx = 0;
				break;
			case '2':
				toplefty = atoi(optarg);
				if(toplefty < 0)
					toplefty = 0;
				break;
			case '3':
				bottomrightx = atoi(optarg);
				if(bottomrightx < 0)
					bottomrightx = WIDTH;
				break;
			case '4':
				bottomrighty = atoi(optarg);
				if(bottomrighty < 0)
					bottomrighty = HEIGHT;
				break;
		}
	}

	//Testando comunicação com a câmera
	if(!ImagemConectar(rgb, dispositivo)) {
		perror("Erro ao inicializar a câmera.");
		exit(EXIT_FAILURE);
	}
	
    ImagemAlterarContraste(rgb, contraste);
    ImagemAlterarBrilho(rgb, brilho);	
    

	//Preparando ROI (Region of Interest)
	cvSetImageROI(
		rgb->frame,
		cvRect(topleftx, toplefty, bottomrightx - topleftx,
			   bottomrighty - toplefty)
	);

	//Iniciando PenServer com pipe
#if defined(WIN32) || defined(MINGW32)
   	sprintf(cmd, "python penserver.py -p %lu --p1x=%d --p1y=%d --p2x=%d --p2y=%d",
   	              porta, topleftx, toplefty, bottomrightx, bottomrighty);
#elif defined(linux)
	sprintf(cmd, "penserver -p %lu --p1x=%d --p1y=%d --p2x=%d --p2y=%d",
	             porta, topleftx, toplefty, bottomrightx, bottomrighty);
#endif
	penserver = popen(cmd, "w");
	if(penserver == NULL) {
		perror("Erro na criação do pipeline!");
		exit(EXIT_FAILURE);
	}

	//Configurando manipulador do sinal SIGTERM
	signal(SIGTERM, sair);
	
	//Loop principal
	ImagemAbrirJanela();
	cvSetMouseCallback(JANELA, evento_mouse, 0);
	while(continuar) {
		ImagemObterFrame(rgb);
		if(ImagemDetectarLaser(rgb)) {
			sprintf(msg,"%u,%u\n", rgb->laser.x, rgb->laser.y);
			fputs(msg, penserver);
			fflush(penserver);
		}
		ImagemDestacarLaser(rgb);
		ImagemExibir(rgb);
		tecla = cvWaitKey(10);
		switch(tecla) {
		    case 's':
		        printf("Salvando imagem em " TMPIMAGE "...\n");
		        ImagemSalvar(rgb, TMPIMAGE);
		        break;
		    case 27: //Tecla ESC
		        continuar = 0;
		        break;
		    case 'k':
		        printf("Aumentando contraste...\n");
		        contraste += 0.1;
		        ImagemAlterarContraste(rgb, contraste);
		        break;
		    case 'h':
		        printf("Diminuindo contraste...\n");
		        contraste -= 0.1;
		        ImagemAlterarContraste(rgb, contraste);
		        break;
		    case 'u':
		        printf("Aumentando brilho...\n");		    
		        brilho += 0.05;
    		    ImagemAlterarBrilho(rgb, brilho);
		        break;
		    case 'j':
		        printf("Diminuindo brilho...\n");
		        brilho -= 0.05;
		        ImagemAlterarBrilho(rgb, brilho);
		        break;       
		}
	}
	ImagemFecharJanela();
	ImagemLiberar(rgb);
	fclose(penserver);
}

static void sair(int signum) {
	ImagemFecharJanela();
	ImagemLiberar(rgb);
	fclose(penserver);
}

static void evento_mouse(int event, int x, int y, int flags, void *params) {
    Cor corrgb;
    Cor corhsv;
    if(event == CV_EVENT_LBUTTONDOWN) {
        ImagemObterCor(rgb, &corrgb, &corhsv, x, y);
        printf("Cores: BGR(%d,%d,%d)  HSV(%d,%d,%d)\n",
            corrgb.c1, corrgb.c2, corrgb.c3,
            corhsv.c1, corhsv.c2, corhsv.c3
        );
    }
}
